package com.s4j.core.hibernate;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.s4j.core.datagrid.DatagridPaging;

@SuppressWarnings("unchecked")
@Repository
public class CommonDao extends HibernateDaoSupport {

	@Autowired  
    public void setSessionFactoryOverride(SessionFactory sessionFactory) {  
        super.setSessionFactory(sessionFactory);  
    }
	
	public Session getSession() {  
        //事务必须是开启的(Required)，否则获取不到  
        return this.getSessionFactory().getCurrentSession();  
    }
	
	public <T> T get(Class<T> clazz, Serializable id) {
		return this.getHibernateTemplate().get(clazz, id);
	}
	
	public Serializable save(Object entity) {
		return this.getHibernateTemplate().save(entity);
	}
	
	public void update(Object entity) {
		this.getHibernateTemplate().update(entity);
	}
	
	public List<Object> findByHQL(String hql, Object ... params) {
        Query query = this.getSession().createQuery(hql);  
        for (int i = 0; params != null && i < params.length; i++) {  
            query.setParameter(i, params[i]);  
        }  
        return query.list();  
    }
	
	public <T> List<T> findByHQL(String hql, Class<T> clazz, Object ... params) {
        Query query = this.getSession().createQuery(hql);  
        for (int i = 0; params != null && i < params.length; i++) {  
            query.setParameter(i, params[i]);  
        }  
        return query.list();
    }
	
	public DatagridPaging findByHQLPaging(String hql, Object ... params) {
        Query query = this.getSession().createQuery(hql);  
        for (int i = 0; params != null && i < params.length-2; i++) {  
            query.setParameter(i, params[i]);  
        }
        query.setFirstResult(((Integer)params[params.length-2]-1) * 10);
        query.setMaxResults((Integer)params[params.length-1]);
        
//        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        
        List<Object> dataList = query.list();
        
        DatagridPaging dp = new DatagridPaging();

        dp.setRows(dataList);
		
		Query query2 = this.getSession().createQuery(hql);  
        for (int i = 0; params != null && i < params.length-2; i++) {  
            query2.setParameter(i, params[i]);  
        }
		
        dp.setTotal(query2.list().size());
        
        return dp;
    }
	

	
	public DatagridPaging findByHqlPagingFormatMap(String hql, Object ... params) {
        Query query = this.getSession().createQuery(hql);  
        for (int i = 0; params != null && i < params.length-2; i++) {  
            query.setParameter(i, params[i]);  
        }
        query.setFirstResult(((Integer)params[params.length-2]-1) * 10);
        query.setMaxResults((Integer)params[params.length-1]);
        
        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        
        List<Object> dataList = query.list();
        
        DatagridPaging dp = new DatagridPaging();

        dp.setRows(dataList);
		
		Query query2 = this.getSession().createQuery(hql);  
        for (int i = 0; params != null && i < params.length-2; i++) {  
            query2.setParameter(i, params[i]);  
        }
		
        dp.setTotal(query2.list().size());
        
        return dp;
    }
	
	public DatagridPaging findByHQLPaging(String countHql, String columnHql, int start, int limit, List<Object> params) {
        Query query = this.getSession().createQuery(countHql);  
        for (int i = 0; i<params.size(); i++) {  
            query.setParameter(i, params.get(i));  
        }
        
        DatagridPaging dp = new DatagridPaging();
		
        dp.setTotal(query.list().size());
		
		Query query2 = this.getSession().createQuery(columnHql);
		for (int i = 0; i<params.size(); i++) {  
            query2.setParameter(i, params.get(i));  
        }  
        
        query2.setFirstResult((start-1) * limit);
        query2.setMaxResults(limit);
        
        List<Object> dataList = query2.list();

        dp.setRows(dataList);
        
        return dp;
    }
	
	/**
	 * 
	 * @param hql
	 * @param clazz
	 * @param params
	 * @return
	 */
	public <T> T findByHQLUnique(String hql, Class<T> clazz, Object ... params) {
		Query query = this.getSession().createQuery(hql);  
        for (int i = 0; params != null && i < params.length; i++) {  
            query.setParameter(i, params[i]);  
        }  
        return (T) query.uniqueResult();
    }

	public <T> void remove(Class<T> clazz, Serializable id) {
		T targer = get(clazz, id);
		if(targer != null) {
			this.getHibernateTemplate().delete(get(clazz, id));
		}
	}

	public void remove(Object obj) {
		this.getHibernateTemplate().delete(obj);
	}
	
	public Object queryBySql(String sql, Object... params) {
		Query query = this.getSession().createSQLQuery(sql);  
        for (int i = 0; params != null && i < params.length; i++) {  
            query.setParameter(i, params[i]);  
        }  
        return query.list();
	}
	
	public int executeSql(String sql, Object... params) {
		Query query = this.getSession().createSQLQuery(sql);  
        for (int i = 0; params != null && i < params.length; i++) {  
            query.setParameter(i, params[i]);  
        }
        return query.executeUpdate();
	}
}
